/*
 * File: ftk_xul.cpp
 * Author:  Jiao JinXing <jiaojinxing1987@gmail.com>
 * Brief:   ftk xml ui loader.
 *
 * Copyright (c) 2010 - 2011  Jiao JinXing <jiaojinxing1987@gmail.com>
 *
 * Licensed under the Academic Free License version 2.1
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * History:
 * ================================================================
 * Jiao JinXing <jiaojinxing1987@gmail.com> created
 *
 */

#include "ftk_xul.h"

typedef enum _FtkWidgetAttr {
    FTK_ATTR_TRANSPARENT     = 1,
    FTK_ATTR_NO_FOCUS        = 1<<1,
    FTK_ATTR_BG_CENTER       = 1<<2,
    FTK_ATTR_BG_TILE         = 1<<3,
    FTK_ATTR_BG_FOUR_CORNER  = 1<<4,
    FTK_ATTR_INSENSITIVE     = 1<<5,
    FTK_ATTR_FOCUSED         = 1<<6,
    FTK_ATTR_IGNORE_CLOSE    = 1<<7, /*for window only*/
    FTK_ATTR_QUIT_WHEN_CLOSE = 1<<8, /*for window only*/
    FTK_ATTR_AUTO_LAYOUT     = 1<<9, /*for dialog only*/
    FTK_ATTR_POPUP           = 1<<10,/*for dialog only*/
    FTK_ATTR_FULLSCREEN      = 1<<11 /*for window only*/
} FtkWidgetAttr;

typedef enum _FtkAlignment {
    FTK_ALIGN_LEFT = 0,
    FTK_ALIGN_RIGHT,
    FTK_ALIGN_CENTER
} FtkAlignment;

typedef enum _FtkInputType {
    FTK_INPUT_NORMAL= 0,
    FTK_INPUT_DIGIT,
    FTK_INPUT_ALPHA,
    FTK_INPUT_URL,
    FTK_INPUT_EMAIL,
    FTK_INPUT_ALL
} FtkInputType;

typedef struct _VarConst {
    const char* name;
    int value;
} VarConst;

const VarConst s_var_conts[] = {
    {"FTK_ATTR_TRANSPARENT",     FTK_ATTR_TRANSPARENT},
    {"FTK_ATTR_IGNORE_CLOSE",    FTK_ATTR_IGNORE_CLOSE},
    {"FTK_ATTR_BG_CENTER",       FTK_ATTR_BG_CENTER},
    {"FTK_ATTR_BG_TILE",         FTK_ATTR_BG_TILE},
    {"FTK_ATTR_BG_FOUR_CORNER",  FTK_ATTR_BG_FOUR_CORNER},
    {"FTK_ATTR_NO_FOCUS",        FTK_ATTR_NO_FOCUS},
    {"FTK_ATTR_INSENSITIVE",     FTK_ATTR_INSENSITIVE},
    {"FTK_ATTR_FOCUSED",         FTK_ATTR_FOCUSED},
    {"FTK_ATTR_QUIT_WHEN_CLOSE", FTK_ATTR_QUIT_WHEN_CLOSE},
    {"FTK_ATTR_FULLSCREEN",      FTK_ATTR_FULLSCREEN},

    {"FTK_ALIGN_LEFT",           FTK_ALIGN_LEFT},
    {"FTK_ALIGN_RIGHT",          FTK_ALIGN_RIGHT},
    {"FTK_ALIGN_CENTER",         FTK_ALIGN_CENTER},

    {"FTK_INPUT_NORMAL",         FTK_INPUT_NORMAL},
    {"FTK_INPUT_DIGIT",          FTK_INPUT_DIGIT},
    {"FTK_INPUT_ALPHA",          FTK_INPUT_ALPHA},
    {"FTK_INPUT_URL",            FTK_INPUT_URL},
    {"FTK_INPUT_EMAIL",          FTK_INPUT_EMAIL},
    {"FTK_INPUT_ALL",            FTK_INPUT_ALL},

    {NULL, 0},
};

int  FtkXul::displayWidth;
int  FtkXul::displayHeight;
int  FtkXul::windowWidth;
int  FtkXul::windowHeight;

FtkXul::FtkXul()
{
}

int FtkXul::ftk_find_const(const char* name)
{
    int i = 0;

    return_val_if_fail(name != NULL, -1);

    for(i = 0; s_var_conts[i].name != NULL; i++) {
        if(strncmp(s_var_conts[i].name, name, strlen(s_var_conts[i].name)) == 0) {
            return i;
        }
    }
    return -1;
}

int FtkXul::ftk_find_const_value(const char* name)
{
    int i = 0;

    return_val_if_fail(name != NULL, 0);

    if (name[0] == '$') {
        name++;
    }

    i = ftk_find_const(name);
    if (i < 0) {
        return 0;
    } else {
        return s_var_conts[i].value;
    }
}

int FtkXul::ftk_find_getter(const char* name)
{
    if (strncmp(name, "pw", 2) == 0) {
        return 0;
    } else if (strncmp(name, "ph", 2) == 0) {
        return 1;
    } else if (strncmp(name, "ww", 2) == 0) {
        return 2;
    } else if (strncmp(name, "wh", 2) == 0) {
        return 3;
    } else if (strncmp(name, "dw", 2) == 0) {
        return 4;
    } else if (strncmp(name, "dh", 2) == 0) {
        return 5;
    } else {
        return -1;
    }
}

const char* FtkXul::ftk_get_getter_name(int i)
{
    switch(i) {
    case 0:
       return "pw";
    case 1:
       return "ph";
    case 2:
       return "ww";
    case 3:
       return "wh";
    case 4:
       return "dw";
    case 5:
       return "dh";

    default:
       return NULL;
    }
}

int FtkXul::ftk_get_getter_value(QWidget *widget, int i)
{
    switch(i) {
    case 0:
       return ftk_get_parent_width(widget);
    case 1:
       return ftk_get_parent_height(widget);
    case 2:
       return ftk_get_window_width(widget);
    case 3:
       return ftk_get_window_height(widget);
    case 4:
       return ftk_get_display_width(widget);
    case 5:
       return ftk_get_display_height(widget);

    default:
       return -1;
    }
}

const char* FtkXul::ftk_preprocess_value(QWidget *widget, const char* value)
{
    int i = 0;
    int dst = 0;
    const char* iter = NULL;
    static char processed_value[128];

    return_val_if_fail(value != NULL, NULL);

    memset(processed_value, 0, sizeof(processed_value));

    for(iter = value; *iter && dst < sizeof(processed_value); iter++) {
        if(*iter == '$') {
            char value[32] = {0};
            int len = sizeof(processed_value)-dst;

            if((i = ftk_find_getter(iter+1)) >= 0) {
                ftk_itoa(value, sizeof(value), ftk_get_getter_value(widget, i));
                if(len > strlen(value)) {
                    strcpy(processed_value+dst, value);
                    dst += strlen(processed_value+dst);
                    iter += strlen(ftk_get_getter_name(i));
                }
                continue;
            } else if((i = ftk_find_const(iter+1)) >= 0) {
                ftk_itoa(value, sizeof(value), s_var_conts[i].value);
                if(len > strlen(value)) {
                    strcpy(processed_value+dst, value);
                    dst += strlen(processed_value+dst);
                    iter += strlen(s_var_conts[i].name);
                }
                continue;
            }
        }

        processed_value[dst++] = *iter;
    }

    processed_value[dst] = '\0';

    return processed_value;
}
